﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using motion.Calibrators;
using Mahanet.Abyss.PathCalculation;
using motion.Properties;

namespace motion
{
  public partial class AimerCalibrationWindow : Form
  {
    private AimerCalibrator m_Calibrator;

    // zero-zero, horiz0, horiz1, vert0, vert1
    private const int c_TurretLocationsCount = 5;
    private Coordinate3D[] m_TurretLocations;

    // TopLeft, BottomLeft, BottomRight
    private const int c_DangerZoneCount = 3;
    private Coordinate3D[] m_DangerZoneLocations;

    private CrossLayer m_Cross0;
    private CrossLayer m_Cross1;

    private Coordinate2D m_LocationXAxis;
    private Coordinate2D m_LocationZAxis;

    public AimerCalibrationWindow(Camera xAxisCam, Camera zAxisCam, Coordinate3DAimer aimer)
    {
      InitializeComponent();

      m_TurretLocations = new Coordinate3D[c_TurretLocationsCount];
      m_DangerZoneLocations = new Coordinate3D[c_DangerZoneCount];

      camw_WindXAxis.Camera = xAxisCam;
      camw_WindZAxis.Camera = zAxisCam;

      m_Cross0 = new CrossLayer(camw_WindXAxis);
      m_Cross1 = new CrossLayer(camw_WindZAxis);

      m_Calibrator = new AimerCalibrator(aimer);

    }

    private void camw_WindXAxis_MouseClick(object sender, MouseEventArgs e)
    {
      m_Cross0.ClearCrosses();
      m_LocationZAxis = new Coordinate2D(e.X, e.Y);
      m_Cross0.AddCross(m_LocationZAxis, Color.AliceBlue);

      var pt = GetSelectedLocationWorldSpace();
      tb_Xm.Text = Math.Round(pt.X, 4).ToString();
      tb_Zm.Text = Math.Round(pt.Z, 4).ToString();
    }

    private void camw_WindZAxis_MouseClick(object sender, MouseEventArgs e)
    {
      m_Cross1.ClearCrosses();
      m_LocationXAxis = new Coordinate2D(e.X, e.Y);
      m_Cross1.AddCross(m_LocationXAxis, Color.AliceBlue);


      var pt = GetSelectedLocationWorldSpace();
      tb_Xm.Text = Math.Round(pt.X, 4).ToString();
      tb_Zm.Text = Math.Round(pt.Z, 4).ToString();
    }

    /// <summary>
    /// Retrieves the 3D location in world space of the selected location, based
    /// on marked points on both camera windows.
    /// </summary>
    /// <returns></returns>
    private Coordinate3D GetSelectedLocationWorldSpace()
    {
      if (m_LocationXAxis == null)
      {
        m_LocationXAxis = new Coordinate2D(0, 0);
      }
      if (m_LocationZAxis == null)
      {
        m_LocationZAxis = new Coordinate2D(0, 0);
      }
      Coordinate3D selectedPoint = ImageTo3DTranslator.GetScreenPointIn3DSpaceP(
        (int)m_LocationXAxis.X,
        (int) m_LocationZAxis.X,
        (int)m_LocationXAxis.Y, 
        camw_WindXAxis.ClientSize.Width,
        camw_WindXAxis.ClientSize.Height);
      selectedPoint = ImageTo3DTranslator.ToMeters(selectedPoint, camw_WindXAxis.ClientSize.Width, Settings.Default.CameraDistanceFromTurret);
      return selectedPoint;
    }

    private void btn_SetZeroZero_Click(object sender, EventArgs e)
    {
      m_TurretLocations[0] = GetSelectedLocationWorldSpace();
      Coordinate2D  cam0Point;
      Coordinate2D cam1Point;
      ImageTo3DTranslator.GetWorldPointOnScreen(
        m_TurretLocations[0].X,
        m_TurretLocations[0].Y,
        m_TurretLocations[0].Z,
        out cam0Point,
        out cam1Point,
        camw_WindXAxis,
        camw_WindZAxis);

      m_Cross0.AddCross(cam0Point, Color.OliveDrab);
      m_Cross1.AddCross(cam1Point, Color.OliveDrab);
    }

    private void btn_SetHoriz0_Click(object sender, EventArgs e)
    {
      m_TurretLocations[1] = GetSelectedLocationWorldSpace();
    }

    private void btn_SetHoriz1_Click(object sender, EventArgs e)
    {
      m_TurretLocations[2] = GetSelectedLocationWorldSpace();
    }

    private void btn_SetVert0_Click(object sender, EventArgs e)
    {
      m_TurretLocations[3] = GetSelectedLocationWorldSpace();
    }

    private void btn_SetVert1_Click(object sender, EventArgs e)
    {
      m_TurretLocations[4] = GetSelectedLocationWorldSpace();
    }


    private void btn_SetDangerZoneTopLeft_Click(object sender, EventArgs e)
    {
      m_DangerZoneLocations[0] = GetSelectedLocationWorldSpace();
    }

    private void btn_SetDangerZoneBottomLeft_Click(object sender, EventArgs e)
    {
      m_DangerZoneLocations[1] = GetSelectedLocationWorldSpace();
    }

    private void btn_SetDangerZoneBottomRight_Click(object sender, EventArgs e)
    {
      m_DangerZoneLocations[2] = GetSelectedLocationWorldSpace();
    }

    private void btn_Calibrate_Click(object sender, EventArgs e)
    {
      m_Calibrator.CalibrateMovement(
        m_TurretLocations[0],
        m_TurretLocations[1],
        m_TurretLocations[2],
        m_TurretLocations[3],
        m_TurretLocations[4]);

      m_Calibrator.CalibrateDangerZone(
        dangerZoneTopLeftEdge: m_DangerZoneLocations[0],
        dangerZoneBottomLeftEdge: m_DangerZoneLocations[1],
        dangerZoneBottomRightEdge: m_DangerZoneLocations[2]);
    }



  }
}
